Skip to content

feat(cloudflare): Add R2 bucket auto-instrumentation#21327

Open
JPeer264 wants to merge 1 commit into
developfrom
jp/cloudflare-r2-instrumentation
Open

feat(cloudflare): Add R2 bucket auto-instrumentation#21327
JPeer264 wants to merge 1 commit into
developfrom
jp/cloudflare-r2-instrumentation

Conversation

@JPeer264
Copy link
Copy Markdown
Member

@JPeer264 JPeer264 commented Jun 3, 2026

closes #20836
closes JS-2448

This implements R2 spans. All attributes were taken from Cloudflare itself. The only thing which does not exist in Cloudflare and is added here (inspired by AWS S3), is cloudflare.r2.bucket and gives information of the binding itself.

This should be merged after the Sentry conventions PR


AI generated text:

Auto-detect R2 bucket bindings via duck-typing in instrumentEnv and wrap all operations with spans. Span names and attributes align with Cloudflare's built-in tracing conventions (r2_get, r2_put, etc.).

Instrumented methods: get, head, put, delete, list, createMultipartUpload, resumeMultipartUpload, and the resulting multipart upload operations (uploadPart, abort, complete).

@JPeer264 JPeer264 self-assigned this Jun 3, 2026
@JPeer264 JPeer264 requested a review from a team as a code owner June 3, 2026 13:21
@JPeer264 JPeer264 requested review from andreiborza and mydea and removed request for a team June 3, 2026 13:21
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 3605367. Configure here.

Comment on lines +75 to +82
export function isR2Bucket(item: unknown): item is R2Bucket {
return (
item != null &&
isNotJSRPC(item) &&
typeof item.head === 'function' &&
typeof item.put === 'function' &&
typeof item.createMultipartUpload === 'function'
);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: The isR2Bucket function uses fragile duck-typing to detect R2 buckets, which could misidentify other objects and lacks test coverage for validation.
Severity: LOW

Suggested Fix

Add comprehensive unit tests for the isR2Bucket function in isBinding.test.ts. The tests should cover positive and negative cases, including objects that have some but not all of the required methods, to ensure the detection logic is robust and prevent future regressions.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location: packages/cloudflare/src/utils/isBinding.ts#L75-L82

Potential issue: The `isR2Bucket` function identifies R2 buckets by checking for the
presence of `head`, `put`, and `createMultipartUpload` methods. This duck-typing
approach is inherently fragile and could lead to false positives. If a different type of
object, such as a custom user object or a future Cloudflare binding, happens to have the
same method names, it would be incorrectly wrapped for R2 instrumentation. This would
not cause a crash but would generate incorrect telemetry spans, which could mislead
debugging efforts. The analysis highlights that this new function lacks any test
coverage in `isBinding.test.ts`, unlike other binding detection functions in the same
file.

Also affects:

  • packages/cloudflare/src/instrumentations/worker/instrumentEnv.ts:57~62

Did we get this right? 👍 / 👎 to inform future reviews.

@linear-code
Copy link
Copy Markdown

linear-code Bot commented Jun 3, 2026

JS-2448

@JPeer264 JPeer264 requested review from isaacs and removed request for mydea June 3, 2026 13:32
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 3, 2026

size-limit report 📦

Path Size % Change Change
@sentry/browser 27.2 kB - -
@sentry/browser - with treeshaking flags 25.65 kB - -
@sentry/browser (incl. Tracing) 45.25 kB - -
@sentry/browser (incl. Tracing + Span Streaming) 47.48 kB - -
@sentry/browser (incl. Tracing, Profiling) 50.24 kB - -
@sentry/browser (incl. Tracing, Replay) 84.87 kB - -
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 74.44 kB - -
@sentry/browser (incl. Tracing, Replay with Canvas) 89.58 kB - -
@sentry/browser (incl. Tracing, Replay, Feedback) 102.2 kB - -
@sentry/browser (incl. Feedback) 44.36 kB - -
@sentry/browser (incl. sendFeedback) 32.02 kB - -
@sentry/browser (incl. FeedbackAsync) 37.11 kB - -
@sentry/browser (incl. Metrics) 28.27 kB - -
@sentry/browser (incl. Logs) 28.51 kB - -
@sentry/browser (incl. Metrics & Logs) 29.22 kB - -
@sentry/react 29.03 kB - -
@sentry/react (incl. Tracing) 47.52 kB - -
@sentry/vue 32.22 kB - -
@sentry/vue (incl. Tracing) 47.17 kB - -
@sentry/svelte 27.23 kB - -
CDN Bundle 29.57 kB - -
CDN Bundle (incl. Tracing) 47.82 kB - -
CDN Bundle (incl. Logs, Metrics) 31.08 kB - -
CDN Bundle (incl. Tracing, Logs, Metrics) 49.06 kB - -
CDN Bundle (incl. Replay, Logs, Metrics) 70.36 kB - -
CDN Bundle (incl. Tracing, Replay) 85.22 kB - -
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) 86.39 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback) 91.08 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) 92.23 kB - -
CDN Bundle - uncompressed 87.7 kB - -
CDN Bundle (incl. Tracing) - uncompressed 144.13 kB - -
CDN Bundle (incl. Logs, Metrics) - uncompressed 92.19 kB - -
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed 147.88 kB - -
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed 217 kB - -
CDN Bundle (incl. Tracing, Replay) - uncompressed 262.99 kB - -
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed 266.74 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 276.69 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed 280.42 kB - -
@sentry/nextjs (client) 50.05 kB - -
@sentry/sveltekit (client) 45.71 kB - -
@sentry/core/server 75.94 kB - -
@sentry/core/browser 63.09 kB - -
@sentry/node-core 61.69 kB -0.01% -1 B 🔽
@sentry/node 130.4 kB - -
@sentry/node - without tracing 74.06 kB -0.01% -1 B 🔽
@sentry/aws-serverless 86.26 kB - -
@sentry/cloudflare (withSentry) - minified 176.19 kB +1.51% +2.6 kB 🔺
⛔️ @sentry/cloudflare (withSentry) (max: 435.2 kB) 438.71 kB +1.18% +5.1 kB 🔺

View base workflow run

Auto-detect R2 bucket bindings via duck-typing in instrumentEnv and
wrap all operations with spans. Span names and attributes align with
Cloudflare's built-in tracing conventions (r2_get, r2_put, etc.).

Instrumented methods: get, head, put, delete, list,
createMultipartUpload, resumeMultipartUpload, and the resulting
multipart upload operations (uploadPart, abort, complete).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@JPeer264 JPeer264 force-pushed the jp/cloudflare-r2-instrumentation branch from 3605367 to 3671f29 Compare June 3, 2026 13:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Cloudflare R2 instrumentation

1 participant